<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
  <meta name="theme-color" content="#222">
  <meta name="generator" content="Hexo 5.4.0">


  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

  <link rel="stylesheet" href="/css/main.css">



  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.15.2/css/all.min.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/animate.css@3.1.1/animate.min.css">

  <script class="hexo-configurations">
    var NexT = window.NexT || {};
    var CONFIG = {
      "hostname": "holidaypenguin.gitee.io",
      "root": "/",
      "images": "/images",
      "scheme": "Mist",
      "version": "8.2.2",
      "exturl": false,
      "sidebar": {
        "position": "right",
        "display": "always",
        "padding": 18,
        "offset": 12
      },
      "copycode": true,
      "bookmark": {
        "enable": false,
        "color": "#222",
        "save": "auto"
      },
      "fancybox": false,
      "mediumzoom": false,
      "lazyload": false,
      "pangu": false,
      "comments": {
        "style": "tabs",
        "active": null,
        "storage": true,
        "lazyload": false,
        "nav": null
      },
      "motion": {
        "enable": true,
        "async": true,
        "transition": {
          "post_block": "fadeIn",
          "post_header": "fadeInDown",
          "post_body": "fadeInDown",
          "coll_header": "fadeInLeft",
          "sidebar": "slideUpIn"
        }
      },
      "prism": false,
      "i18n": {
        "placeholder": "搜索...",
        "empty": "没有找到任何搜索结果：${query}",
        "hits_time": "找到 ${hits} 个搜索结果（用时 ${time} 毫秒）",
        "hits": "找到 ${hits} 个搜索结果"
      },
      "path": "/search.xml",
      "localsearch": {
        "enable": true,
        "trigger": "auto",
        "top_n_per_article": 1,
        "unescape": false,
        "preload": false
      }
    };
  </script>
  <meta property="og:type" content="article">
  <meta property="og:title" content="npm模块管理器">
  <meta property="og:url" content="https://holidaypenguin.gitee.io/blob/2017-09-11-npm-module-manager/index.html">
  <meta property="og:site_name" content="HolidayPenguin">
  <meta property="og:locale" content="zh_CN">
  <meta property="article:published_time" content="2017-09-11T08:19:54.000Z">
  <meta property="article:modified_time" content="2017-09-11T08:19:54.000Z">
  <meta property="article:author" content="holidaypenguin">
  <meta property="article:tag" content="Npm">
  <meta name="twitter:card" content="summary">


  <link rel="canonical" href="https://holidaypenguin.gitee.io/blob/2017-09-11-npm-module-manager/">


  <script class="page-configurations">
    // https://hexo.io/docs/variables.html
    CONFIG.page = {
      sidebar: "",
      isHome: false,
      isPost: true,
      lang: 'zh-CN'
    };
  </script>
  <title>npm模块管理器 | HolidayPenguin</title>





  <noscript>
    <style>
      body {
        margin-top: 2rem;
      }

      .use-motion .menu-item,
      .use-motion .sidebar,
      .use-motion .post-block,
      .use-motion .pagination,
      .use-motion .comments,
      .use-motion .post-header,
      .use-motion .post-body,
      .use-motion .collection-header {
        visibility: visible;
      }

      .use-motion .header,
      .use-motion .site-brand-container .toggle,
      .use-motion .footer {
        opacity: initial;
      }

      .use-motion .site-title,
      .use-motion .site-subtitle,
      .use-motion .custom-logo-image {
        opacity: initial;
        top: initial;
      }

      .use-motion .logo-line {
        transform: scaleX(1);
      }

      .search-pop-overlay,
      .sidebar-nav {
        display: none;
      }

      .sidebar-panel {
        display: block;
      }
    </style>
  </noscript>

</head>

<body itemscope itemtype="http://schema.org/WebPage" class="use-motion">
  <div class="headband"></div>

  <main class="main">
    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner">
        <div class="site-brand-container">
          <div class="site-nav-toggle">
            <div class="toggle" aria-label="切换导航栏" role="button">
              <span class="toggle-line"></span>
              <span class="toggle-line"></span>
              <span class="toggle-line"></span>
            </div>
          </div>

          <div class="site-meta">

            <a href="/" class="brand" rel="start">
              <i class="logo-line"></i>
              <h1 class="site-title">HolidayPenguin</h1>
              <i class="logo-line"></i>
            </a>
          </div>

          <div class="site-nav-right">
            <div class="toggle popup-trigger">
              <i class="fa fa-search fa-fw fa-lg"></i>
            </div>
          </div>
        </div>



        <nav class="site-nav">
          <ul class="main-menu menu">
            <li class="menu-item menu-item-home"><a href="/" rel="section"><i class="fa fa-home fa-fw"></i>首页</a></li>
            <li class="menu-item menu-item-tags"><a href="/tags/" rel="section"><i class="fa fa-tags fa-fw"></i>标签</a></li>
            <li class="menu-item menu-item-categories"><a href="/categories/" rel="section"><i class="fa fa-th fa-fw"></i>分类</a></li>
            <li class="menu-item menu-item-archives"><a href="/archives/" rel="section"><i class="fa fa-archive fa-fw"></i>归档</a></li>
            <li class="menu-item menu-item-search">
              <a role="button" class="popup-trigger"><i class="fa fa-search fa-fw"></i>搜索
              </a>
            </li>
          </ul>
        </nav>



        <div class="search-pop-overlay">
          <div class="popup search-popup">
            <div class="search-header">
              <span class="search-icon">
                <i class="fa fa-search"></i>
              </span>
              <div class="search-input-container">
                <input autocomplete="off" autocapitalize="off" maxlength="80" placeholder="搜索..." spellcheck="false" type="search" class="search-input">
              </div>
              <span class="popup-btn-close" role="button">
                <i class="fa fa-times-circle"></i>
              </span>
            </div>
            <div class="search-result-container no-result">
              <div class="search-result-icon">
                <i class="fa fa-spinner fa-pulse fa-5x"></i>
              </div>
            </div>

          </div>
        </div>

      </div>


      <div class="toggle sidebar-toggle" role="button">
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
      </div>

      <aside class="sidebar">

        <div class="sidebar-inner sidebar-nav-active sidebar-toc-active">
          <ul class="sidebar-nav">
            <li class="sidebar-nav-toc">
              文章目录
            </li>
            <li class="sidebar-nav-overview">
              站点概览
            </li>
          </ul>

          <div class="sidebar-panel-container">
            <!--noindex-->
            <div class="post-toc-wrap sidebar-panel">
              <div class="post-toc animated">
                <ol class="nav">
                  <li class="nav-item nav-level-1"><a class="nav-link" href="#%E7%AE%80%E4%BB%8B"><span class="nav-number">1.</span> <span class="nav-text">简介</span></a></li>
                  <li class="nav-item nav-level-1"><a class="nav-link" href="#npm-init"><span class="nav-number">2.</span> <span class="nav-text">npm init</span></a></li>
                  <li class="nav-item nav-level-1"><a class="nav-link" href="#npm-set"><span class="nav-number">3.</span> <span class="nav-text">npm set</span></a></li>
                  <li class="nav-item nav-level-1"><a class="nav-link" href="#npm-config"><span class="nav-number">4.</span> <span class="nav-text">npm config</span></a></li>
                  <li class="nav-item nav-level-1"><a class="nav-link" href="#npm-info"><span class="nav-number">5.</span> <span class="nav-text">npm info</span></a></li>
                  <li class="nav-item nav-level-1"><a class="nav-link" href="#npm-search"><span class="nav-number">6.</span> <span class="nav-text">npm search</span></a></li>
                  <li class="nav-item nav-level-1"><a class="nav-link" href="#npm-list"><span class="nav-number">7.</span> <span class="nav-text">npm list</span></a></li>
                  <li class="nav-item nav-level-1"><a class="nav-link" href="#npm-install"><span class="nav-number">8.</span> <span class="nav-text">npm install</span></a>
                    <ol class="nav-child">
                      <li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95"><span class="nav-number">8.1.</span> <span class="nav-text">基本用法</span></a></li>
                      <li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%AE%89%E8%A3%85%E4%B8%8D%E5%90%8C%E7%89%88%E6%9C%AC"><span class="nav-number">8.2.</span> <span class="nav-text">安装不同版本</span></a></li>
                    </ol>
                  </li>
                  <li class="nav-item nav-level-1"><a class="nav-link" href="#%E9%81%BF%E5%85%8D%E7%B3%BB%E7%BB%9F%E6%9D%83%E9%99%90"><span class="nav-number">9.</span> <span class="nav-text">避免系统权限</span></a></li>
                  <li class="nav-item nav-level-1"><a class="nav-link" href="#npm-update%EF%BC%8Cnpm-uninstall"><span class="nav-number">10.</span> <span class="nav-text">npm update，npm uninstall</span></a></li>
                  <li class="nav-item nav-level-1"><a class="nav-link" href="#npm-run"><span class="nav-number">11.</span> <span class="nav-text">npm run</span></a>
                    <ol class="nav-child">
                      <li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%8F%82%E6%95%B0"><span class="nav-number">11.1.</span> <span class="nav-text">参数</span></a></li>
                      <li class="nav-item nav-level-2"><a class="nav-link" href="#scripts%E8%84%9A%E6%9C%AC%E5%91%BD%E4%BB%A4%E6%9C%80%E4%BD%B3%E5%AE%9E%E8%B7%B5"><span class="nav-number">11.2.</span> <span class="nav-text">scripts脚本命令最佳实践</span></a></li>
                      <li class="nav-item nav-level-2"><a class="nav-link" href="#pre-%E5%92%8C-post-%E8%84%9A%E6%9C%AC"><span class="nav-number">11.3.</span> <span class="nav-text">pre- 和 post- 脚本</span></a></li>
                      <li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%86%85%E9%83%A8%E5%8F%98%E9%87%8F"><span class="nav-number">11.4.</span> <span class="nav-text">内部变量</span></a></li>
                      <li class="nav-item nav-level-2"><a class="nav-link" href="#%E9%80%9A%E9%85%8D%E7%AC%A6"><span class="nav-number">11.5.</span> <span class="nav-text">通配符</span></a></li>
                    </ol>
                  </li>
                  <li class="nav-item nav-level-1"><a class="nav-link" href="#npm-link"><span class="nav-number">12.</span> <span class="nav-text">npm link</span></a></li>
                  <li class="nav-item nav-level-1"><a class="nav-link" href="#npm-bin"><span class="nav-number">13.</span> <span class="nav-text">npm bin</span></a></li>
                  <li class="nav-item nav-level-1"><a class="nav-link" href="#npm-adduser"><span class="nav-number">14.</span> <span class="nav-text">npm adduser</span></a></li>
                  <li class="nav-item nav-level-1"><a class="nav-link" href="#npm-publish"><span class="nav-number">15.</span> <span class="nav-text">npm publish</span></a></li>
                  <li class="nav-item nav-level-1"><a class="nav-link" href="#npm-deprecate"><span class="nav-number">16.</span> <span class="nav-text">npm deprecate</span></a></li>
                  <li class="nav-item nav-level-1"><a class="nav-link" href="#%E5%85%B6%E4%BB%96%E5%91%BD%E4%BB%A4"><span class="nav-number">17.</span> <span class="nav-text">其他命令</span></a>
                    <ol class="nav-child">
                      <li class="nav-item nav-level-2"><a class="nav-link" href="#npm-home%EF%BC%8Cnpm-repo"><span class="nav-number">17.1.</span> <span class="nav-text">npm home，npm repo</span></a></li>
                      <li class="nav-item nav-level-2"><a class="nav-link" href="#npm-outdated"><span class="nav-number">17.2.</span> <span class="nav-text">npm outdated</span></a></li>
                      <li class="nav-item nav-level-2"><a class="nav-link" href="#npm-prune"><span class="nav-number">17.3.</span> <span class="nav-text">npm prune</span></a></li>
                      <li class="nav-item nav-level-2"><a class="nav-link" href="#npm-shrinkwrap"><span class="nav-number">17.4.</span> <span class="nav-text">npm shrinkwrap</span></a></li>
                    </ol>
                  </li>
                  <li class="nav-item nav-level-1"><a class="nav-link" href="#%E4%B8%8A%E6%96%87%E5%8E%9F%E6%96%87%E5%9C%B0%E5%9D%80"><span class="nav-number">18.</span> <span class="nav-text">上文原文地址</span></a></li>
                  <li class="nav-item nav-level-1"><a class="nav-link" href="#%E7%AC%AC%E4%B8%89%E6%96%B9npm"><span class="nav-number">19.</span> <span class="nav-text">第三方npm</span></a>
                    <ol class="nav-child">
                      <li class="nav-item nav-level-2"><a class="nav-link" href="#cnpm"><span class="nav-number">19.1.</span> <span class="nav-text">cnpm</span></a></li>
                      <li class="nav-item nav-level-2"><a class="nav-link" href="#verdaccio"><span class="nav-number">19.2.</span> <span class="nav-text">verdaccio</span></a></li>
                    </ol>
                  </li>
                  <li class="nav-item nav-level-1"><a class="nav-link" href="#npm-%E4%B8%8B%E8%BD%BD%E9%87%8F%E7%BB%9F%E8%AE%A1"><span class="nav-number">20.</span> <span class="nav-text">npm 下载量统计</span></a></li>
                </ol>
              </div>
            </div>
            <!--/noindex-->

            <div class="site-overview-wrap sidebar-panel">
              <div class="site-author site-overview-item animated" itemprop="author" itemscope itemtype="http://schema.org/Person">
                <p class="site-author-name" itemprop="name">holidaypenguin</p>
                <div class="site-description" itemprop="description"></div>
              </div>
              <div class="site-state-wrap site-overview-item animated">
                <nav class="site-state">
                  <div class="site-state-item site-state-posts">
                    <a href="/archives/">

                      <span class="site-state-item-count">138</span>
                      <span class="site-state-item-name">日志</span>
                    </a>
                  </div>
                  <div class="site-state-item site-state-categories">
                    <a href="/categories/">

                      <span class="site-state-item-count">26</span>
                      <span class="site-state-item-name">分类</span></a>
                  </div>
                  <div class="site-state-item site-state-tags">
                    <a href="/tags/">

                      <span class="site-state-item-count">234</span>
                      <span class="site-state-item-name">标签</span></a>
                  </div>
                </nav>
              </div>
              <div class="links-of-author site-overview-item animated">
                <span class="links-of-author-item">
                  <a href="https://github.com/holidaypenguin" title="GitHub → https:&#x2F;&#x2F;github.com&#x2F;holidaypenguin" rel="noopener" target="_blank"><i class="github fa-fw"></i>GitHub</a>
                </span>
                <span class="links-of-author-item">
                  <a href="mailto:songshipeng2016@gmail.com" title="E-Mail → mailto:songshipeng2016@gmail.com" rel="noopener" target="_blank"><i class="envelope fa-fw"></i>E-Mail</a>
                </span>
              </div>



            </div>
          </div>
        </div>
      </aside>
      <div class="sidebar-dimmer"></div>


    </header>


    <div class="back-to-top" role="button">
      <i class="fa fa-arrow-up"></i>
      <span>0%</span>
    </div>

    <noscript>
      <div class="noscript-warning">Theme NexT works best with JavaScript enabled</div>
    </noscript>


    <div class="main-inner post posts-expand">





      <div class="post-block">



        <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="zh-CN">
          <link itemprop="mainEntityOfPage" href="https://holidaypenguin.gitee.io/blob/2017-09-11-npm-module-manager/">

          <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
            <meta itemprop="image" content="/images/avatar.gif">
            <meta itemprop="name" content="holidaypenguin">
            <meta itemprop="description" content="">
          </span>

          <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
            <meta itemprop="name" content="HolidayPenguin">
          </span>
          <header class="post-header">
            <h1 class="post-title" itemprop="name headline">
              npm模块管理器
            </h1>

            <div class="post-meta-container">
              <div class="post-meta">
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-calendar"></i>
                  </span>
                  <span class="post-meta-item-text">发表于</span>

                  <time title="创建时间：2017-09-11 16:19:54" itemprop="dateCreated datePublished" datetime="2017-09-11T16:19:54+08:00">2017-09-11</time>
                </span>
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-folder"></i>
                  </span>
                  <span class="post-meta-item-text">分类于</span>
                  <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                    <a href="/categories/Npm/" itemprop="url" rel="index"><span itemprop="name">Npm</span></a>
                  </span>
                </span>


                <span id="/blob/2017-09-11-npm-module-manager/" class="post-meta-item leancloud_visitors" data-flag-title="npm模块管理器" title="阅读次数">
                  <span class="post-meta-item-icon">
                    <i class="far fa-eye"></i>
                  </span>
                  <span class="post-meta-item-text">阅读次数：</span>
                  <span class="leancloud-visitors-count"></span>
                </span>
              </div>

              <div class="post-description">
                <!-- more -->
              </div>
            </div>
          </header>




          <div class="post-body" itemprop="articleBody">
            <h1 id="简介"><a href="#简介" class="headerlink" title="简介"></a>简介</h1>
            <p><code>npm</code>有两层含义。一层含义是Node的开放式模块登记和管理系统，网址为npmjs.org。另一层含义是Node默认的模块管理器，是一个命令行下的软件，用来安装和管理Node模块。</p>
            <p><code>npm</code>不需要单独安装。在安装Node的时候，会连带一起安装<code>npm</code>。但是，Node附带的<code>npm</code>可能不是最新版本，最好用下面的命令，更新到最新版本。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ npm install npm@latest -g</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>
            <p>上面的命令中，<code>@latest</code>表示最新版本，<code>-g</code>表示全局安装。所以，命令的主干是<code>npm install npm</code>，也就是使用npm安装自己。之所以可以这样，是因为npm本身与Node的其他模块没有区别。</p>
            <p>然后，运行下面的命令，查看各种信息。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line"><span class="comment"># 查看 npm 命令列表</span></span><br><span class="line">$ npm <span class="built_in">help</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 查看各个命令的简单用法</span></span><br><span class="line">$ npm -l</span><br><span class="line"></span><br><span class="line"><span class="comment"># 查看 npm 的版本</span></span><br><span class="line">$ npm -v</span><br><span class="line"></span><br><span class="line"><span class="comment"># 查看 npm 的配置</span></span><br><span class="line">$ npm config list -l</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <h1 id="npm-init"><a href="#npm-init" class="headerlink" title="npm init"></a>npm init</h1>
            <p><code>npm init</code>用来初始化生成一个新的<code>package.json</code>文件。它会向用户提问一系列问题，如果你觉得不用修改默认配置，一路回车就可以了。</p>
            <p>如果使用了<code>-f</code>（代表force）、-y（代表yes），则跳过提问阶段，直接生成一个新的package.json文件。</p>
            <figure class="highlight plain">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ npm init -y</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <h1 id="npm-set"><a href="#npm-set" class="headerlink" title="npm set"></a>npm set</h1>
            <p>npm set用来设置环境变量。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ npm <span class="built_in">set</span> init-author-name <span class="string">&#x27;Your name&#x27;</span></span><br><span class="line">$ npm <span class="built_in">set</span> init-author-email <span class="string">&#x27;Your email&#x27;</span></span><br><span class="line">$ npm <span class="built_in">set</span> init-author-url <span class="string">&#x27;http://yourdomain.com&#x27;</span></span><br><span class="line">$ npm <span class="built_in">set</span> init-license <span class="string">&#x27;MIT&#x27;</span></span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>上面命令等于为<code>npm init</code>设置了默认值，以后执行<code>npm init</code>的时候，<code>package.json</code>的作者姓名、邮件、主页、许可证字段就会自动写入预设的值。这些信息会存放在用户主目录的 <code>~/.npmrc</code>文件，使得用户不用每个项目都输入。如果某个项目有不同的设置，可以针对该项目运行<code>npm config</code>。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ npm <span class="built_in">set</span> save-exact <span class="literal">true</span></span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>上面命令设置加入模块时，package.json将记录模块的确切版本，而不是一个可选的版本范围。</p>
            <h1 id="npm-config"><a href="#npm-config" class="headerlink" title="npm config"></a>npm config</h1>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ npm config <span class="built_in">set</span> prefix <span class="variable">$dir</span></span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>
            <p>上面的命令将指定的<code>$dir</code>目录，设为模块的全局安装目录。如果当前有这个目录的写权限，那么运行<code>npm install</code>的时候，就不再需要<code>sudo</code>命令授权了。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ npm config <span class="built_in">set</span> save-prefix ~</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>上面的命令使得<code>npm install --save</code>和<code>npm install --save-dev</code>安装新模块时，允许的版本范围从克拉符号（<code>^</code>）改成波浪号（<code>~</code>），即从允许小版本升级，变成只允许补丁包的升级。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ npm config <span class="built_in">set</span> init.author.name <span class="variable">$name</span></span><br><span class="line">$ npm config <span class="built_in">set</span> init.author.email <span class="variable">$email</span></span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>上面命令指定使用<code>npm init</code>时，生成的<code>package.json</code>文件的字段默认值。</p>
            <h1 id="npm-info"><a href="#npm-info" class="headerlink" title="npm info"></a>npm info</h1>
            <p><code>npm info</code>命令可以查看每个模块的具体信息。比如，查看<code>underscore</code>模块的信息。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ npm info underscore</span><br><span class="line">&#123; name: <span class="string">&#x27;underscore&#x27;</span>,</span><br><span class="line">  description: <span class="string">&#x27;JavaScript\&#x27;</span>s functional programming helper library.<span class="string">&#x27;,</span></span><br><span class="line"><span class="string">  &#x27;</span>dist-tags<span class="string">&#x27;: &#123; latest: &#x27;</span>1.5.2<span class="string">&#x27;, stable: &#x27;</span>1.5.2<span class="string">&#x27; &#125;,</span></span><br><span class="line"><span class="string">  repository:</span></span><br><span class="line"><span class="string">   &#123; type: &#x27;</span>git<span class="string">&#x27;,</span></span><br><span class="line"><span class="string">     url: &#x27;</span>git://github.com/jashkenas/underscore.git<span class="string">&#x27; &#125;,</span></span><br><span class="line"><span class="string">  homepage: &#x27;</span>http://underscorejs.org<span class="string">&#x27;,</span></span><br><span class="line"><span class="string">  main: &#x27;</span>underscore.js<span class="string">&#x27;,</span></span><br><span class="line"><span class="string">  version: &#x27;</span>1.5.2<span class="string">&#x27;,</span></span><br><span class="line"><span class="string">  devDependencies: &#123; phantomjs: &#x27;</span>1.9.0-1<span class="string">&#x27; &#125;,</span></span><br><span class="line"><span class="string">  licenses:</span></span><br><span class="line"><span class="string">   &#123; type: &#x27;</span>MIT<span class="string">&#x27;,</span></span><br><span class="line"><span class="string">     url: &#x27;</span>https://raw.github.com/jashkenas/underscore/master/LICENSE<span class="string">&#x27; &#125;,</span></span><br><span class="line"><span class="string">  files:</span></span><br><span class="line"><span class="string">   [ &#x27;</span>underscore.js<span class="string">&#x27;,</span></span><br><span class="line"><span class="string">     &#x27;</span>underscore-min.js<span class="string">&#x27;,</span></span><br><span class="line"><span class="string">     &#x27;</span>LICENSE<span class="string">&#x27; ],</span></span><br><span class="line"><span class="string">  readmeFilename: &#x27;</span>README.md<span class="string">&#x27;&#125;</span></span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>上面命令返回一个JavaScript对象，包含了underscore模块的详细信息。这个对象的每个成员，都可以直接从info命令查询。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ npm info underscore description</span><br><span class="line">JavaScript<span class="string">&#x27;s functional programming helper library.</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">$ npm info underscore homepage</span></span><br><span class="line"><span class="string">http://underscorejs.org</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">$ npm info underscore version</span></span><br><span class="line"><span class="string">1.5.2</span></span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <h1 id="npm-search"><a href="#npm-search" class="headerlink" title="npm search"></a>npm search</h1>
            <p><code>npm search</code>命令用于搜索npm仓库，它后面可以跟字符串，也可以跟正则表达式。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ npm search &lt;搜索词&gt;</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>下面是一个例子。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ npm search node-gyp</span><br><span class="line">// NAME                  DESCRIPTION</span><br><span class="line">// autogypi              Autogypi handles dependencies <span class="keyword">for</span> node-gyp projects.</span><br><span class="line">// grunt-node-gyp        Run node-gyp commands from Grunt.</span><br><span class="line">// gyp-io                Temporary solution to <span class="built_in">let</span> node-gyp run `rebuild` under…</span><br><span class="line">// ...</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <h1 id="npm-list"><a href="#npm-list" class="headerlink" title="npm list"></a>npm list</h1>
            <p><code>npm list</code>命令以树型结构列出当前项目安装的所有模块，以及它们依赖的模块。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ npm list</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>加上global参数，会列出全局安装的模块。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ npm list -global</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p><code>npm list</code>命令也可以列出单个模块。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ npm list underscore</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <h1 id="npm-install"><a href="#npm-install" class="headerlink" title="npm install"></a>npm install</h1>
            <h2 id="基本用法"><a href="#基本用法" class="headerlink" title="基本用法"></a>基本用法</h2>
            <p>Node模块采用<code>npm install</code>命令安装。</p>
            <p>每个模块可以“全局安装”，也可以“本地安装”。“全局安装”指的是将一个模块安装到系统目录中，各个项目都可以调用。一般来说，全局安装只适用于工具模块，比如<code>eslint</code>和<code>gulp</code>。“本地安装”指的是将一个模块下载到当前项目的node_modules子目录，然后只有在项目目录之中，才能调用这个模块。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line"><span class="comment"># 本地安装</span></span><br><span class="line">$ npm install &lt;package name&gt;</span><br><span class="line"></span><br><span class="line"><span class="comment"># 全局安装</span></span><br><span class="line">$ sudo npm install -global &lt;package name&gt;</span><br><span class="line">$ sudo npm install -g &lt;package name&gt;</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p><code>npm install</code>也支持直接输入Github代码库地址。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ npm install git://github.com/package/path.git</span><br><span class="line">$ npm install git://github.com/package/path.git<span class="comment">#0.1.0</span></span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>安装之前，<code>npm install</code>会先检查，<code>node_modules</code>目录之中是否已经存在指定模块。如果存在，就不再重新安装了，即使远程仓库已经有了一个新版本，也是如此。</p>
            <p>如果你希望，一个模块不管是否安装过，<code>npm</code> 都要强制重新安装，可以使用<code>-f</code>或<code>--force</code>参数。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ npm install &lt;packageName&gt; --force</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>如果你希望，所有模块都要强制重新安装，那就删除<code>node_modules</code>目录，重新执行<code>npm install</code>。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ rm -rf node_modules</span><br><span class="line">$ npm install</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <h2 id="安装不同版本"><a href="#安装不同版本" class="headerlink" title="安装不同版本"></a>安装不同版本</h2>
            <p><code>install</code>命令总是安装模块的最新版本，如果要安装模块的特定版本，可以在模块名后面加上@和版本号。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ npm install sax@latest</span><br><span class="line">$ npm install sax@0.1.1</span><br><span class="line">$ npm install sax@<span class="string">&quot;&gt;=0.1.0 &lt;0.2.0&quot;</span></span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>如果使用<code>--save-exact</code>参数，会在<code>package.json</code>文件指定安装模块的确切版本。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ npm install readable-stream --save --save-exact</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p><code>install</code>命令可以使用不同参数，指定所安装的模块属于哪一种性质的依赖关系，即出现在packages.json文件的哪一项中。</p>
            <blockquote>
              <p>–save：模块名将被添加到dependencies，可以简化为参数-S。<br>–save-dev: 模块名将被添加到devDependencies，可以简化为参数-D。</p>
            </blockquote>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ npm install sax --save</span><br><span class="line">$ npm install node-tap --save-dev</span><br><span class="line"><span class="comment"># 或者</span></span><br><span class="line">$ npm install sax -S</span><br><span class="line">$ npm install node-tap -D</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>如果要安装beta版本的模块，需要使用下面的命令。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line"><span class="comment"># 安装最新的beta版</span></span><br><span class="line">$ npm install &lt;module-name&gt;@beta (latest beta)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 安装指定的beta版</span></span><br><span class="line">$ npm install &lt;module-name&gt;@1.3.1-beta.3</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p><code>npm install</code>默认会安装<code>dependencies</code>字段和<code>devDependencies</code>字段中的所有模块，如果使用<code>--production</code>参数，可以只安装<code>dependencies</code>字段的模块。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ npm install --production</span><br><span class="line"><span class="comment"># 或者</span></span><br><span class="line">$ NODE_ENV=production npm install</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>一旦安装了某个模块，就可以在代码中用require命令加载这个模块。</p>
            <figure class="highlight javascript">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line"><span class="keyword">var</span> backbone = <span class="built_in">require</span>(<span class="string">&#x27;backbone&#x27;</span>)</span><br><span class="line"><span class="built_in">console</span>.log(backbone.VERSION)</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <h1 id="避免系统权限"><a href="#避免系统权限" class="headerlink" title="避免系统权限"></a>避免系统权限</h1>
            <p>默认情况下，Npm全局模块都安装在系统目录（比如<code>/usr/local/lib/</code>），普通用户没有写入权限，需要用到sudo命令。这不是很方便，我们可以在没有root权限的情况下，安装全局模块。</p>
            <p>首先，在主目录下新建配置文件<code>.npmrc</code>，然后在该文件中将<code>prefix</code>变量定义到主目录下面。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">prefix = /home/yourUsername/npm</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>然后在主目录下新建npm子目录。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ mkdir ~/npm</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>此后，全局安装的模块都会安装在这个子目录中，npm也会到<code>~/npm/bin</code>目录去寻找命令。</p>
            <p>最后，将这个路径在<code>.bash_profile</code>文件（或<code>.bashrc</code>文件）中加入PATH变量。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line"><span class="built_in">export</span> PATH=~/npm/bin:<span class="variable">$PATH</span></span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>
            <h1 id="npm-update，npm-uninstall"><a href="#npm-update，npm-uninstall" class="headerlink" title="npm update，npm uninstall"></a>npm update，npm uninstall</h1>
            <p><code>npm update</code>命令可以更新本地安装的模块。</p>
            <figure class="highlight plain">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line"># 升级当前项目的指定模块</span><br><span class="line">$ npm update [package name]</span><br><span class="line"></span><br><span class="line"># 升级全局安装的模块</span><br><span class="line">$ npm update -global [package name]</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>它会先到远程仓库查询最新版本，然后查询本地版本。如果本地版本不存在，或者远程版本较新，就会安装。</p>
            <p>使用<code>-S</code>或<code>--save</code>参数，可以在安装的时候更新package.json里面模块的版本号。</p>
            <figure class="highlight">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line"><span class="comment">// 更新之前的package.json</span></span><br><span class="line">dependencies: &#123;</span><br><span class="line">  dep1: &quot;^1.1.1&quot;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 更新之后的package.json</span></span><br><span class="line">dependencies: &#123;</span><br><span class="line">  dep1: &quot;^1.2.2&quot;</span><br><span class="line">&#125;</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>注意，从npm v2.6.1 开始，<code>npm update</code>只更新顶层模块，而不更新依赖的依赖，以前版本是递归更新的。如果想取到老版本的效果，要使用下面的命令。</p>
            <figure class="highlight plain">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ npm --depth 9999 update</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p><code>npm uninstall</code>命令，卸载已安装的模块。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ npm uninstall [package name]</span><br><span class="line"></span><br><span class="line"><span class="comment"># 卸载全局模块</span></span><br><span class="line">$ npm uninstall [package name] -global</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <h1 id="npm-run"><a href="#npm-run" class="headerlink" title="npm run"></a>npm run</h1>
            <p><code>npm</code>不仅可以用于模块管理，还可以用于执行脚本。<code>package.json</code>文件有一个<code>scripts</code>字段，可以用于指定脚本命令，供<code>npm</code>直接调用。</p>
            <figure class="highlight json">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">&#123;</span><br><span class="line">  <span class="attr">&quot;name&quot;</span>: <span class="string">&quot;myproject&quot;</span>,</span><br><span class="line">  <span class="attr">&quot;devDependencies&quot;</span>: &#123;</span><br><span class="line">    <span class="attr">&quot;jshint&quot;</span>: <span class="string">&quot;latest&quot;</span>,</span><br><span class="line">    <span class="attr">&quot;browserify&quot;</span>: <span class="string">&quot;latest&quot;</span>,</span><br><span class="line">    <span class="attr">&quot;mocha&quot;</span>: <span class="string">&quot;latest&quot;</span></span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="attr">&quot;scripts&quot;</span>: &#123;</span><br><span class="line">    <span class="attr">&quot;lint&quot;</span>: <span class="string">&quot;jshint **.js&quot;</span>,</span><br><span class="line">    <span class="attr">&quot;test&quot;</span>: <span class="string">&quot;mocha test/&quot;</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>上面代码中，<code>scripts</code>字段指定了两项命令<code>lint</code>和<code>test</code>。命令行输入<code>npm run-script lint</code>或者<code>npm run lint</code>，就会执行<code>jshint **.js</code>，输入<code>npm run-script test</code>或者<code>npm run test</code>，就会执行<code>mocha test/</code>。<code>npm run</code>是<code>npm run-script</code>的缩写，一般都使用前者，但是后者可以更好地反应这个命令的本质。</p>
            <p><code>npm run</code>命令会自动在环境变量<code>$PATH</code>添加<code>node_modules/.bin</code>目录，所以<code>scripts</code>字段里面调用命令时不用加上路径，这就避免了全局安装NPM模块。</p>
            <p><code>npm run</code>如果不加任何参数，直接运行，会列出<code>package.json</code>里面所有可以执行的脚本命令。</p>
            <p><code>npm</code>内置了两个命令简写，<code>npm test</code>等同于执行<code>npm run test</code>，<code>npm start</code>等同于执行<code>npm run start</code>。</p>
            <p><code>npm run</code>会创建一个<code>Shell</code>，执行指定的命令，并临时将<code>node_modules/.bin</code>加入<code>PATH</code>变量，这意味着本地模块可以直接运行。</p>
            <p>举例来说，你执行ESLint的安装命令。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ npm i eslint --save-dev</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>运行上面的命令以后，会产生两个结果。首先，ESLint被安装到当前目录的<code>node_modules</code>子目录；其次，<code>node_modules/.bin</code>目录会生成一个符号链接<code>node_modules/.bin/eslint</code>，指向ESLint模块的可执行脚本。</p>
            <p>然后，你就可以在<code>package.json</code>的<code>script</code>属性里面，不带路径的引用<code>eslint</code>这个脚本。</p>
            <figure class="highlight json">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">&#123;</span><br><span class="line">  <span class="attr">&quot;name&quot;</span>: <span class="string">&quot;Test Project&quot;</span>,</span><br><span class="line">  <span class="attr">&quot;devDependencies&quot;</span>: &#123;</span><br><span class="line">    <span class="attr">&quot;eslint&quot;</span>: <span class="string">&quot;^1.10.3&quot;</span></span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="attr">&quot;scripts&quot;</span>: &#123;</span><br><span class="line">    <span class="attr">&quot;lint&quot;</span>: <span class="string">&quot;eslint .&quot;</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>等到运行<code>npm run lint</code>的时候，它会自动执行<code>./node_modules/.bin/eslint .</code>。</p>
            <p>如果直接运行<code>npm run</code>不给出任何参数，就会列出<code>scripts</code>属性下所有命令。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ npm run</span><br><span class="line">Available scripts <span class="keyword">in</span> the user-service package:</span><br><span class="line">  lint</span><br><span class="line">     jshint **.js</span><br><span class="line">  <span class="built_in">test</span></span><br><span class="line">    mocha <span class="built_in">test</span>/</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>下面是另一个<code>package.json</code>文件的例子。</p>
            <figure class="highlight">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">&quot;scripts&quot;: &#123;</span><br><span class="line">  &quot;watch&quot;: &quot;watchify client/main.js -o public/app.js -v&quot;,</span><br><span class="line">  &quot;build&quot;: &quot;browserify client/main.js -o public/app.js&quot;,</span><br><span class="line">  &quot;start&quot;: &quot;npm run watch &amp; nodemon server.js&quot;,</span><br><span class="line">  &quot;test&quot;: &quot;node test/all.js&quot;</span><br><span class="line">&#125;,</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>上面代码在<code>scripts</code>项，定义了四个别名，每个别名都有对应的脚本命令。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ npm run watch</span><br><span class="line">$ npm run build</span><br><span class="line">$ npm run start</span><br><span class="line">$ npm run <span class="built_in">test</span></span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>其中，<code>start</code>和<code>test</code>属于特殊命令，可以省略run。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ npm start</span><br><span class="line">$ npm <span class="built_in">test</span></span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>如果希望一个操作的输出，是另一个操作的输入，可以借用Linux系统的管道命令，将两个操作连在一起。</p>
            <figure class="highlight shell">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">&quot;build-js&quot;: &quot;browserify browser/main.js | uglifyjs -mc &gt; static/bundle.js&quot;</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>
            <p>但是，更方便的写法是引用其他<code>npm run</code>命令。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line"><span class="string">&quot;build&quot;</span>: <span class="string">&quot;npm run build-js &amp;&amp; npm run build-css&quot;</span></span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>上面的写法是先运行<code>npm run build-js</code>，然后再运行<code>npm run build-css</code>，两个命令中间用<code>&amp;&amp;</code>连接。如果希望两个命令同时平行执行，它们中间可以用<code>&amp;</code>连接。</p>
            <p>下面是一个流操作的例子。</p>
            <figure class="highlight">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">&quot;devDependencies&quot;: &#123;</span><br><span class="line">  &quot;autoprefixer&quot;: &quot;latest&quot;,</span><br><span class="line">  &quot;cssmin&quot;: &quot;latest&quot;</span><br><span class="line">&#125;,</span><br><span class="line"></span><br><span class="line">&quot;scripts&quot;: &#123;</span><br><span class="line">  &quot;build:css&quot;: &quot;autoprefixer -b &#x27;last 2 versions&#x27; &lt; assets/styles/main.css | cssmin &gt; dist/main.css&quot;</span><br><span class="line">&#125;</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>写在<code>scripts</code>属性中的命令，也可以在<code>node_modules/.bin</code>目录中直接写成bash脚本。下面是一个bash脚本。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line"><span class="meta">#!/bin/bash</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">cd</span> site/main</span><br><span class="line">browserify browser/main.js | uglifyjs -mc &gt; static/bundle.js</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>假定上面的脚本文件名为build.sh，并且权限为可执行，就可以在scripts属性中引用该文件。</p>
            <figure class="highlight javascript">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line"><span class="string">&quot;build-js&quot;</span>: <span class="string">&quot;bin/build.sh&quot;</span></span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <h2 id="参数"><a href="#参数" class="headerlink" title="参数"></a>参数</h2>
            <p><code>npm run</code>命令还可以添加参数。</p>
            <figure class="highlight">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">&quot;scripts&quot;: &#123;</span><br><span class="line">  &quot;test&quot;: &quot;mocha test/&quot;</span><br><span class="line">&#125;</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>上面代码指定<code>npm test</code>，实际运行<code>mocha test/</code>。如果要通过<code>npm test</code>命令，将参数传到<code>mocha</code>，则参数之前要加上两个连词线。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ npm run <span class="built_in">test</span> -- anothertest.js</span><br><span class="line"><span class="comment"># 等同于</span></span><br><span class="line">$ mocha <span class="built_in">test</span>/ anothertest.js</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>上面命令表示，mocha要运行所有<code>test</code>子目录的测试脚本，以及另外一个测试脚本<code>anothertest.js</code>。</p>
            <p><code>npm run</code>本身有一个参数<code>-s</code>，表示关闭<code>npm</code>本身的输出，只输出脚本产生的结果。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">// 输出npm命令头</span><br><span class="line">$ npm run <span class="built_in">test</span></span><br><span class="line"></span><br><span class="line">// 不输出npm命令头</span><br><span class="line">$ npm run -s <span class="built_in">test</span></span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <h2 id="scripts脚本命令最佳实践"><a href="#scripts脚本命令最佳实践" class="headerlink" title="scripts脚本命令最佳实践"></a>scripts脚本命令最佳实践</h2>
            <p><code>scripts</code>字段的脚本命令，有一些最佳实践，可以方便开发。首先，安装<code>npm-run-all</code>模块。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ npm install npm-run-all --save-dev</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>这个模块用于运行多个scripts脚本命令。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line"><span class="comment"># 继发执行</span></span><br><span class="line">$ npm-run-all build:html build:js</span><br><span class="line"><span class="comment"># 等同于</span></span><br><span class="line">$ npm run build:html &amp;&amp; npm run build:js</span><br><span class="line"></span><br><span class="line"><span class="comment"># 并行执行</span></span><br><span class="line">$ npm-run-all --parallel watch:html watch:js</span><br><span class="line"><span class="comment"># 等同于</span></span><br><span class="line">$ npm run watch:html &amp; npm run watch:js</span><br><span class="line"></span><br><span class="line"><span class="comment"># 混合执行</span></span><br><span class="line">$ npm-run-all clean lint --parallel watch:html watch:js</span><br><span class="line"><span class="comment"># 等同于</span></span><br><span class="line">$ npm-run-all clean lint</span><br><span class="line">$ npm-run-all --parallel watch:html watch:js</span><br><span class="line"></span><br><span class="line"><span class="comment"># 通配符</span></span><br><span class="line">$ npm-run-all --parallel watch:*</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>###（1）start脚本命令</p>
            <p><code>start</code>脚本命令，用于启动应用程序。</p>
            <figure class="highlight">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">&quot;start&quot;: &quot;npm-run-all --parallel dev serve&quot;</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>上面命令并行执行<code>dev</code>脚本命令和<code>serve</code>脚本命令，等同于下面的形式。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ npm run dev &amp; npm run serve</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>如果start脚本没有配置，<code>npm start</code>命令默认执行下面的脚本，前提是模块的根目录存在一个<code>server.js</code>文件。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ node server.js</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>###（2）dev脚本命令</p>
            <p><code>dev</code>脚本命令，规定开发阶段所要做的处理，比如构建网页资源。</p>
            <figure class="highlight">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">&quot;dev&quot;: &quot;npm-run-all dev:*&quot;</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>上面命令用于继发执行所有<code>dev</code>的子命令。</p>
            <figure class="highlight">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">&quot;predev:sass&quot;: &quot;node-sass --source-map src/css/hoodie.css.map --output-style nested src/sass/base.scss src/css/hoodie.css&quot;</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>上面命令将sass文件编译为css文件，并生成source map文件。</p>
            <figure class="highlight">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">&quot;dev:sass&quot;: &quot;node-sass --source-map src/css/hoodie.css.map --watch --output-style nested src/sass/base.scss src/css/hoodie.css&quot;</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>上面命令会监视sass文件的变动，只要有变动，就自动将其编译为css文件。</p>
            <figure class="highlight">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">&quot;dev:autoprefix&quot;: &quot;postcss --use autoprefixer --autoprefixer.browsers \&quot;&gt; 5%\&quot; --output src/css/hoodie.css src/css/hoodie.css&quot;</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>上面命令为css文件加上浏览器前缀，限制条件是只考虑市场份额大于5%的浏览器。</p>
            <p>###（3）serve脚本命令</p>
            <p><code>serve</code>脚本命令用于启动服务。</p>
            <figure class="highlight">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">&quot;serve&quot;: &quot;live-server dist/ --port=9090&quot;</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>上面命令启动服务，用的是<code>live-server</code>模块，将服务启动在<code>9090</code>端口，展示<code>dist</code>子目录。</p>
            <p><code>live-server</code>模块有三个功能。</p>
            <blockquote>
              <p>启动一个HTTP服务器，展示指定目录的index.html文件，通过该文件加载各种网络资源，这是file://协议做不到的。<br>添加自动刷新功能。只要指定目录之中，文件有任何变化，它就会刷新页面。<br>npm run serve命令执行以后，自动打开浏览器。、</p>
            </blockquote>
            <p>以前，上面三个功能需要三个模块来完成：http-server、live-reload和opener，现在只要live-server一个模块就够了。</p>
            <p>###（4）test脚本命令</p>
            <p><code>test</code>脚本命令用于执行测试。</p>
            <figure class="highlight">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">&quot;test&quot;: &quot;npm-run-all test:*&quot;,</span><br><span class="line">&quot;test:lint&quot;: &quot;sass-lint --verbose --config .sass-lint.yml src/sass/*&quot;</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>上面命令规定，执行测试时，运行lint脚本，检查脚本之中的语法错误。</p>
            <p>###（5）prod脚本命令</p>
            <p><code>prod</code>脚本命令，规定进入生产环境时需要做的处理。</p>
            <figure class="highlight">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">&quot;prod&quot;: &quot;npm-run-all prod:*&quot;,</span><br><span class="line">&quot;prod:sass&quot;: &quot;node-sass --output-style compressed src/sass/base.scss src/css/prod/hoodie.min.css&quot;,</span><br><span class="line">&quot;prod:autoprefix&quot;: &quot;postcss --use autoprefixer --autoprefixer.browsers &quot;&gt; 5%&quot; --output src/css/prod/hoodie.min.css src/css/prod/hoodie.min.css&quot;</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>
            <p>上面命令将<code>sass</code>文件转为<code>css</code>文件，并加上浏览器前缀。</p>
            <p>###（6）help脚本命令</p>
            <p><code>help</code>脚本命令用于展示帮助信息。</p>
            <figure class="highlight">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">&quot;help&quot;: &quot;markdown-chalk --input DEVELOPMENT.md&quot;</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>上面命令之中，<code>markdown-chalk</code>模块用于将指定的<code>markdown</code>文件，转为彩色文本显示在终端之中。</p>
            <p>###（7）docs脚本命令</p>
            <p><code>docs</code>脚本命令用于生成文档。</p>
            <figure class="highlight">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">&quot;docs&quot;: &quot;kss-node --source src/sass --homepage ../../styleguide.md&quot;</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>上面命令使用<code>kss-node</code>模块，提供源码的注释生成markdown格式的文档。</p>
            <h2 id="pre-和-post-脚本"><a href="#pre-和-post-脚本" class="headerlink" title="pre- 和 post- 脚本"></a>pre- 和 post- 脚本</h2>
            <p><code>npm run</code>为每条命令提供了<code>pre-</code>和<code>post-</code>两个钩子（hook）。以<code>npm run lint</code>为例，执行这条命令之前，<code>npm</code>会先查看有没有定义<code>prelint</code>和<code>postlint</code>两个钩子，如果有的话，就会先执行<code>npm run prelint</code>，然后执行<code>npm run lint</code>，最后执行<code>npm run postlint</code>。</p>
            <figure class="highlight json">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">&#123;</span><br><span class="line">  <span class="attr">&quot;name&quot;</span>: <span class="string">&quot;myproject&quot;</span>,</span><br><span class="line">  <span class="attr">&quot;devDependencies&quot;</span>: &#123;</span><br><span class="line">    <span class="attr">&quot;eslint&quot;</span>: <span class="string">&quot;latest&quot;</span></span><br><span class="line">    <span class="string">&quot;karma&quot;</span>: <span class="string">&quot;latest&quot;</span></span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="attr">&quot;scripts&quot;</span>: &#123;</span><br><span class="line">    <span class="attr">&quot;lint&quot;</span>: <span class="string">&quot;eslint --cache --ext .js --ext .jsx src&quot;</span>,</span><br><span class="line">    <span class="attr">&quot;test&quot;</span>: <span class="string">&quot;karma start --log-leve=error karma.config.js --single-run=true&quot;</span>,</span><br><span class="line">    <span class="attr">&quot;pretest&quot;</span>: <span class="string">&quot;npm run lint&quot;</span>,</span><br><span class="line">    <span class="attr">&quot;posttest&quot;</span>: <span class="string">&quot;echo &#x27;Finished running tests&#x27;&quot;</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>上面代码是一个<code>package.json</code>文件的例子。如果执行<code>npm test</code>，会按下面的顺序执行相应的命令。</p>
            <ul>
              <li>pretest</li>
              <li>test</li>
              <li>posttest</li>
            </ul>
            <p>如果执行过程出错，就不会执行排在后面的脚本，即如果<code>prelint</code>脚本执行出错，就不会接着执行<code>lint</code>和<code>postlint</code>脚本。</p>
            <p>下面是一个例子。</p>
            <figure class="highlight json">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">&#123;</span><br><span class="line">  <span class="attr">&quot;test&quot;</span>: <span class="string">&quot;karma start&quot;</span>,</span><br><span class="line">  <span class="attr">&quot;test:lint&quot;</span>: <span class="string">&quot;eslint . --ext .js --ext .jsx&quot;</span>,</span><br><span class="line">  <span class="attr">&quot;pretest&quot;</span>: <span class="string">&quot;npm run test:lint&quot;</span></span><br><span class="line">&#125;</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>
            <p>上面代码中，在运行<code>npm run test</code>之前，会自动检查代码，即运行<code>npm run test:lint</code>命令。</p>
            <p>下面是一些常见的<code>pre-</code>和<code>post-</code>脚本。</p>
            <blockquote>
              <p>prepublish：发布一个模块前执行。<br>postpublish：发布一个模块后执行。<br>preinstall：用户执行npm install命令时，先执行该脚本。<br>postinstall：用户执行npm install命令时，安装结束后执行该脚本，通常用于将下载的源码编译成用户需要的格式，比如有些模块需要在用户机器上跟本地的C++模块一起编译。<br>preuninstall：卸载一个模块前执行。<br>postuninstall：卸载一个模块后执行。<br>preversion：更改模块版本前执行。<br>postversion：更改模块版本后执行。<br>pretest：运行npm test命令前执行。<br>posttest：运行npm test命令后执行。<br>prestop：运行npm stop命令前执行。<br>poststop：运行npm stop命令后执行。<br>prestart：运行npm start命令前执行。<br>poststart：运行npm start命令后执行。<br>prerestart：运行npm restart命令前执行。<br>postrestart：运行npm restart命令后执行。</p>
            </blockquote>
            <p>对于最后一个<code>npm restart</code>命令，如果没有设置<code>restart</code>脚本，<code>prerestart</code>和<code>postrestart</code>会依次执行stop和start脚本。</p>
            <p>另外，不能在<code>pre</code>脚本之前再加<code>pre</code>，即<code>prepretest</code>脚本不起作用。</p>
            <p>注意，即使<code>Npm</code>可以自动运行<code>pre</code>和<code>post</code>脚本，也可以手动执行它们。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ npm run prepublish</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>下面是<code>post install</code>的例子。</p>
            <figure class="highlight json">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">&#123;</span><br><span class="line">  <span class="attr">&quot;postinstall&quot;</span>: <span class="string">&quot;node lib/post_install.js&quot;</span></span><br><span class="line">&#125;</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>上面的这个命令，主要用于处理从Git仓库拉下来的源码。比如，有些源码是用TypeScript写的，可能需要转换一下。</p>
            <p>下面是<code>publish</code>钩子的一个例子。</p>
            <figure class="highlight json">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">&#123;</span><br><span class="line">  <span class="attr">&quot;dist:modules&quot;</span>: <span class="string">&quot;babel ./src --out-dir ./dist-modules&quot;</span>,</span><br><span class="line">  <span class="attr">&quot;gh-pages&quot;</span>: <span class="string">&quot;webpack&quot;</span>,</span><br><span class="line">  <span class="attr">&quot;gh-pages:deploy&quot;</span>: <span class="string">&quot;gh-pages -d gh-pages&quot;</span>,</span><br><span class="line">  <span class="attr">&quot;prepublish&quot;</span>: <span class="string">&quot;npm run dist:modules&quot;</span>,</span><br><span class="line">  <span class="attr">&quot;postpublish&quot;</span>: <span class="string">&quot;npm run gh-pages &amp;&amp; npm run gh-pages:deploy&quot;</span></span><br><span class="line">&#125;</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>上面命令在运行<code>npm run publish</code>时，会先执行<code>Babel</code>编译，然后调用<code>Webpack</code>构建，最后发到<code>Github Pages</code>上面。</p>
            <p>以上都是<code>npm</code>相关操作的钩子，如果安装某些模块，还能支持Git相关的钩子。下面以<code>husky</code>模块为例。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ npm install husky --save-dev</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>安装以后，就能在<code>package.json</code>添加<code>precommit</code>、<code>prepush</code>等钩子。</p>
            <figure class="highlight json">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">&#123;</span><br><span class="line">    <span class="attr">&quot;scripts&quot;</span>: &#123;</span><br><span class="line">        <span class="attr">&quot;lint&quot;</span>: <span class="string">&quot;eslint yourJsFiles.js&quot;</span>,</span><br><span class="line">        <span class="attr">&quot;precommit&quot;</span>: <span class="string">&quot;npm run test &amp;&amp; npm run lint&quot;</span>,</span><br><span class="line">        <span class="attr">&quot;prepush&quot;</span>: <span class="string">&quot;npm run test &amp;&amp; npm run lint&quot;</span>,</span><br><span class="line">        <span class="attr">&quot;...&quot;</span>: <span class="string">&quot;...&quot;</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>类似作用的模块还有<code>pre-commit</code>、<code>precommit-hook</code>等。</p>
            <h2 id="内部变量"><a href="#内部变量" class="headerlink" title="内部变量"></a>内部变量</h2>
            <p><code>scripts</code>字段可以使用一些内部变量，主要是<code>package.json</code>的各种字段。</p>
            <p>比如，<code>package.json</code>的内容是<code>&#123;&quot;name&quot;:&quot;foo&quot;, &quot;version&quot;:&quot;1.2.5&quot;&#125;</code>，那么变量<code>npm_package_name</code>的值是<code>foo</code>，变量<code>npm_package_version</code>的值是1.2.5。</p>
            <figure class="highlight json">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">&#123;</span><br><span class="line">  <span class="attr">&quot;scripts&quot;</span>:&#123;</span><br><span class="line">    <span class="attr">&quot;bundle&quot;</span>: <span class="string">&quot;mkdir -p build/$npm_package_version/&quot;</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>运行<code>npm run bundle</code>以后，将会生成<code>build/1.2.5/</code>子目录。</p>
            <p><code>config</code>字段也可以用于设置内部字段。</p>
            <figure class="highlight">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">&quot;name&quot;: &quot;fooproject&quot;,</span><br><span class="line">&quot;config&quot;: &#123;</span><br><span class="line">  &quot;reporter&quot;: &quot;xunit&quot;</span><br><span class="line">&#125;,</span><br><span class="line">&quot;scripts&quot;: &#123;</span><br><span class="line">  &quot;test&quot;: &quot;mocha test/ --reporter $npm_package_config_reporter&quot;</span><br><span class="line">&#125;</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>上面代码中，变量<code>npm_package_config_reporter</code>对应的就是<code>reporter</code>。</p>
            <h2 id="通配符"><a href="#通配符" class="headerlink" title="通配符"></a>通配符</h2>
            <p><code>npm</code>的通配符的规则如下。</p>
            <blockquote>
              <ul>
                <li>匹配0个或多个字符<br>? 匹配1个字符<br>[…] 匹配某个范围的字符。如果该范围的第一个字符是!或^，则匹配不在该范围的字符。<br>!(pattern|pattern|pattern) 匹配任何不符合给定的模式<br>?(pattern|pattern|pattern) 匹配0个或1个给定的模式</li>
              </ul>
              <p>+(pattern|pattern|pattern) 匹配1个或多个给定的模式<br><em>(a|b|c) 匹配0个或多个给定的模式<br>@(pattern|pat</em>|pat?erN) 只匹配给定模式之一<br>** 如果出现在路径部分，表示0个或多个子目录。</p>
            </blockquote>
            <h1 id="npm-link"><a href="#npm-link" class="headerlink" title="npm link"></a>npm link</h1>
            <p>开发NPM模块的时候，有时我们会希望，边开发边试用，比如本地调试的时候，<code>require(&#39;myModule&#39;)</code>会自动加载本机开发中的模块。Node规定，使用一个模块时，需要将其安装到全局的或项目的<code>node_modules</code>目录之中。对于开发中的模块，解决方法就是在全局的node_modules目录之中，生成一个符号链接，指向模块的本地目录。</p>
            <p><code>npm link</code>就能起到这个作用，会自动建立这个符号链接。</p>
            <p>请设想这样一个场景，你开发了一个模块<code>myModule</code>，目录为<code>src/myModule</code>，你自己的项目<code>myProject</code>要用到这个模块，项目目录为<code>src/myProject</code>。首先，在模块目录（<code>src/myModule</code>）下运行<code>npm link</code>命令。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">src/myModule$ npm link</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>上面的命令会在NPM的全局模块目录内，生成一个符号链接文件，该文件的名字就是<code>package.json</code>文件中指定的模块名。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">/path/to/global/node_modules/myModule -&gt; src/myModule</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>这个时候，已经可以全局调用<code>myModule</code>模块了。但是，如果我们要让这个模块安装在项目内，还要进行下面的步骤。</p>
            <p>切换到项目目录，再次运行<code>npm link</code>命令，并指定模块名。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">src/myProject$ npm link myModule</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>上面命令等同于生成了本地模块的符号链接。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">src/myProject/node_modules/myModule -&gt; /path/to/global/node_modules/myModule</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>然后，就可以在你的项目中，加载该模块了。</p>
            <figure class="highlight javascript">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line"><span class="keyword">var</span> myModule = <span class="built_in">require</span>(<span class="string">&#x27;myModule&#x27;</span>);</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>这样一来，<code>myModule</code>的任何变化，都可以直接反映在<code>myProject</code>项目之中。但是，这样也出现了风险，任何在<code>myProject</code>目录中对<code>myModule</code>的修改，都会反映到模块的源码中。</p>
            <p>如果你的项目不再需要该模块，可以在项目目录内使用<code>npm unlink</code>命令，删除符号链接。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">src/myProject$ npm unlink myModule</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <h1 id="npm-bin"><a href="#npm-bin" class="headerlink" title="npm bin"></a>npm bin</h1>
            <p><code>npm bin</code>命令显示相对于当前目录的，Node模块的可执行脚本所在的目录（即<code>.bin</code>目录）。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line"><span class="comment"># 项目根目录下执行</span></span><br><span class="line">$ npm bin</span><br><span class="line">./node_modules/.bin</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <h1 id="npm-adduser"><a href="#npm-adduser" class="headerlink" title="npm adduser"></a>npm adduser</h1>
            <p><code>npm adduser</code>用于在<code>npmjs.com</code>注册一个用户。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ npm adduser</span><br><span class="line">Username: YOUR_USER_NAME</span><br><span class="line">Password: YOUR_PASSWORD</span><br><span class="line">Email: YOUR_EMAIL@domain.com</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <h1 id="npm-publish"><a href="#npm-publish" class="headerlink" title="npm publish"></a>npm publish</h1>
            <p><code>npm publish</code>用于将当前模块发布到<code>npmjs.com</code>。执行之前，需要向npmjs.com申请用户名。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ npm adduser</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>如果已经注册过，就使用下面的命令登录。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ npm login</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>登录以后，就可以使用<code>npm publish</code>命令发布。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ npm publish</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>如果当前模块是一个<code>beta</code>版，比如<code>1.3.1-beta.3</code>，那么发布的时候需要使用<code>tag</code>参数，将其发布到指定标签，默认的发布标签是<code>latest</code>。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ npm publish --tag beta</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>如果发布私有模块，模块初始化的时候，需要加上scope参数。只有npm的付费用户才能发布私有模块。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ npm init --scope=&lt;yourscope&gt;</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>如果你的模块是用ES6写的，那么发布的时候，最好转成ES5。首先，需要安装Babel。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ npm install --save-dev babel-cli@6 babel-preset-es2015@6</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>然后，在package.json里面写入build脚本。</p>
            <figure class="highlight">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">&quot;scripts&quot;: &#123;</span><br><span class="line">  &quot;build&quot;: &quot;babel source --presets babel-preset-es2015 --out-dir distribution&quot;,</span><br><span class="line">  &quot;prepublish&quot;: &quot;npm run build&quot;</span><br><span class="line">&#125;</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>运行上面的脚本，会将<code>source</code>目录里面的ES6源码文件，转为<code>distribution</code>目录里面的ES5源码文件。然后，在项目根目录下面创建两个文件<code>.npmignore</code>和<code>.gitignore</code>，分别写入以下内容。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">// .npmignore</span><br><span class="line"><span class="built_in">source</span></span><br><span class="line"></span><br><span class="line">// .gitignore</span><br><span class="line">node_modules</span><br><span class="line">distribution</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <h1 id="npm-deprecate"><a href="#npm-deprecate" class="headerlink" title="npm deprecate"></a>npm deprecate</h1>
            <p>如果想废弃某个版本的模块，可以使用<code>npm deprecate</code>命令。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ npm deprecate my-thing@<span class="string">&quot;&lt; 0.2.3&quot;</span> <span class="string">&quot;critical bug fixed in v0.2.3&quot;</span></span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>运行上面的命令以后，小于<code>0.2.3</code>版本的模块的<code>package.json</code>都会写入一行警告，用户安装这些版本时，这行警告就会在命令行显示。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">npm owner</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>模块的维护者可以发布新版本。<code>npm owner</code>命令用于管理模块的维护者。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line"><span class="comment"># 列出指定模块的维护者</span></span><br><span class="line">$ npm owner ls &lt;package name&gt;</span><br><span class="line"></span><br><span class="line"><span class="comment"># 新增维护者</span></span><br><span class="line">$ npm owner add &lt;user&gt; &lt;package name&gt;</span><br><span class="line"></span><br><span class="line"><span class="comment"># 删除维护者</span></span><br><span class="line">$ npm owner rm &lt;user&gt; &lt;package name&gt;</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <h1 id="其他命令"><a href="#其他命令" class="headerlink" title="其他命令"></a>其他命令</h1>
            <h2 id="npm-home，npm-repo"><a href="#npm-home，npm-repo" class="headerlink" title="npm home，npm repo"></a>npm home，npm repo</h2>
            <p><code>npm home</code>命令可以打开一个模块的主页，<code>npm repo</code>命令则是打开一个模块的代码仓库。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ npm home <span class="variable">$package</span></span><br><span class="line">$ npm repo <span class="variable">$package</span></span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>这两个命令不需要模块先安装。</p>
            <h2 id="npm-outdated"><a href="#npm-outdated" class="headerlink" title="npm outdated"></a>npm outdated</h2>
            <p><code>npm outdated</code>命令检查当前项目所依赖的模块，是否已经有新版本。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ npm outdated</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>它会输出当前版本（current version）、应当安装的版本（wanted version）和最新发布的版本（latest version）。</p>
            <h2 id="npm-prune"><a href="#npm-prune" class="headerlink" title="npm prune"></a>npm prune</h2>
            <p><code>npm prune</code>检查当前项目的<code>node_modules</code>目录中，是否有<code>package.json</code>里面没有提到的模块，然后将所有这些模块输出在命令行。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ npm prune</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <h2 id="npm-shrinkwrap"><a href="#npm-shrinkwrap" class="headerlink" title="npm shrinkwrap"></a>npm shrinkwrap</h2>
            <p><code>npm shrinkwrap</code>的作用是锁定当前项目的依赖模块的版本。</p>
            <figure class="highlight bash">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">$ npm shrinkwrap</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>运行该命令后，会在当前项目的根目录下生成一个<code>npm-shrinkwrap.json</code>文件，内容是<code>node_modules</code>目录下所有已经安装的模块，以及它们的精确版本。</p>
            <p>下次运行<code>npm install</code>命令时，<code>npm</code>发现当前目录下有<code>npm-shrinkwrap.json</code>文件，就会只安装里面提到的模块，且版本也会保持一致。</p>
            <h1 id="上文原文地址"><a href="#上文原文地址" class="headerlink" title="上文原文地址"></a>上文原文地址</h1>
            <p>** 上文原文地址：<a target="_blank" rel="noopener" href="http://javascript.ruanyifeng.com/nodejs/npm.html#toc19">http://javascript.ruanyifeng.com/nodejs/npm.html#toc19</a> **</p>
            <h1 id="第三方npm"><a href="#第三方npm" class="headerlink" title="第三方npm"></a>第三方npm</h1>
            <h2 id="cnpm"><a href="#cnpm" class="headerlink" title="cnpm"></a>cnpm</h2>
            <p>国产的npm管理，优点是速度快，缺点是定时更新导致更新有延迟</p>
            <h2 id="verdaccio"><a href="#verdaccio" class="headerlink" title="verdaccio"></a>verdaccio</h2>
            <p>github：<a target="_blank" rel="noopener" href="https://github.com/verdaccio/verdaccio">https://github.com/verdaccio/verdaccio</a><br>官网：<a target="_blank" rel="noopener" href="https://www.verdaccio.org/">https://www.verdaccio.org/</a></p>
            <p>相当于把npm内容下载到本地，同时也可以在本地发布</p>
            <h1 id="npm-下载量统计"><a href="#npm-下载量统计" class="headerlink" title="npm 下载量统计"></a>npm 下载量统计</h1>
            <p><a target="_blank" rel="noopener" href="https://npm-stat.com/api/download-counts?package=miniprogram-keyboard-num&amp;from=2018-01-01&amp;until=2019-12-31">https://npm-stat.com/api/download-counts?package=miniprogram-keyboard-num&amp;from=2018-01-01&amp;until=2019-12-31</a></p>
            <p>该接口查看一段时间内每天的下载量，可以自己根据需要做统计</p>

          </div>





          <footer class="post-footer">
            <div class="post-tags">
              <a href="/tags/Npm/" rel="tag"># Npm</a>
            </div>



            <div class="post-nav">
              <div class="post-nav-item">
                <a href="/blob/2017-08-24-fiddler-grab-pack-https/" rel="prev" title="Fiddler抓包https">
                  <i class="fa fa-chevron-left"></i> Fiddler抓包https
                </a>
              </div>
              <div class="post-nav-item">
                <a href="/blob/2017-09-12-installation-and-startup-of-cnpm/" rel="next" title="cnpm安装与启动">
                  cnpm安装与启动 <i class="fa fa-chevron-right"></i>
                </a>
              </div>
            </div>
          </footer>
        </article>
      </div>







      <script>
        window.addEventListener('tabs:register', () => {
          let {
            activeClass
          } = CONFIG.comments;
          if (CONFIG.comments.storage) {
            activeClass = localStorage.getItem('comments_active') || activeClass;
          }
          if (activeClass) {
            const activeTab = document.querySelector(`a[href="#comment-${activeClass}"]`);
            if (activeTab) {
              activeTab.click();
            }
          }
        });
        if (CONFIG.comments.storage) {
          window.addEventListener('tabs:click', event => {
            if (!event.target.matches('.tabs-comment .tab-content .tab-pane')) return;
            const commentClass = event.target.classList[1];
            localStorage.setItem('comments_active', commentClass);
          });
        }
      </script>
    </div>
  </main>

  <footer class="footer">
    <div class="footer-inner">


      <div class="copyright">
        &copy;
        <span itemprop="copyrightYear">2021</span>
        <span class="with-love">
          <i class="fa fa-heart"></i>
        </span>
        <span class="author" itemprop="copyrightHolder">holidaypenguin</span>
      </div>
      <div class="powered-by">由 <a href="https://hexo.io/" class="theme-link" rel="noopener" target="_blank">Hexo</a> & <a href="https://theme-next.js.org/mist/" class="theme-link" rel="noopener" target="_blank">NexT.Mist</a> 强力驱动
      </div>

    </div>
  </footer>


  <script size="300" alpha="0.1" zIndex="-1" src="https://cdn.jsdelivr.net/npm/ribbon.js@1.0.2/dist/ribbon.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/animejs@3.2.1/lib/anime.min.js"></script>
  <script src="/js/love.js"></script>

  <script src="/js/development.js"></script>
  <script src="/js/utils.js"></script>
  <script src="/js/motion.js"></script>
  <script src="/js/schemes/muse.js"></script>
  <script src="/js/next-boot.js"></script>


  <script src="/js/local-search.js"></script>









  <script>
    (function() {
      function leancloudSelector(url) {
        url = encodeURI(url);
        return document.getElementById(url).querySelector('.leancloud-visitors-count');
      }

      function addCount(Counter) {
        const visitors = document.querySelector('.leancloud_visitors');
        const url = decodeURI(visitors.id);
        const title = visitors.dataset.flagTitle;

        Counter('get', '/classes/Counter?where=' + encodeURIComponent(JSON.stringify({
            url
          })))
          .then(response => response.json())
          .then(({
            results
          }) => {
            if (results.length > 0) {
              const counter = results[0];
              leancloudSelector(url).innerText = counter.time + 1;
              Counter('put', '/classes/Counter/' + counter.objectId, {
                  time: {
                    '__op': 'Increment',
                    'amount': 1
                  }
                })
                .catch(error => {
                  console.error('Failed to save visitor count', error);
                });
            } else {
              Counter('post', '/classes/Counter', {
                  title,
                  url,
                  time: 1
                })
                .then(response => response.json())
                .then(() => {
                  leancloudSelector(url).innerText = 1;
                })
                .catch(error => {
                  console.error('Failed to create', error);
                });
            }
          })
          .catch(error => {
            console.error('LeanCloud Counter Error', error);
          });
      }

      function showTime(Counter) {
        const visitors = document.querySelectorAll('.leancloud_visitors');
        const entries = [...visitors].map(element => {
          return decodeURI(element.id);
        });

        Counter('get', '/classes/Counter?where=' + encodeURIComponent(JSON.stringify({
            url: {
              '$in': entries
            }
          })))
          .then(response => response.json())
          .then(({
            results
          }) => {
            for (let url of entries) {
              const target = results.find(item => item.url === url);
              leancloudSelector(url).innerText = target ? target.time : 0;
            }
          })
          .catch(error => {
            console.error('LeanCloud Counter Error', error);
          });
      }

      const {
        app_id,
        app_key,
        server_url
      } = {
        "enable": true,
        "app_id": "povuqNsSqFodlakVIwtEX5kb-gzGzoHsz",
        "app_key": "zXD40RDtDB3DMtpC89k0AK7g",
        "server_url": null,
        "security": false
      };

      function fetchData(api_server) {
        const Counter = (method, url, data) => {
          return fetch(`${api_server}/1.1${url}`, {
            method,
            headers: {
              'X-LC-Id': app_id,
              'X-LC-Key': app_key,
              'Content-Type': 'application/json',
            },
            body: JSON.stringify(data)
          });
        };
        if (CONFIG.page.isPost) {
          if (CONFIG.hostname !== location.hostname) return;
          addCount(Counter);
        } else if (document.querySelectorAll('.post-title-link').length >= 1) {
          showTime(Counter);
        }
      }

      const api_server = app_id.slice(-9) === '-MdYXbMMI' ? `https://${app_id.slice(0, 8).toLowerCase()}.api.lncldglobal.com` : server_url;

      if (api_server) {
        fetchData(api_server);
      } else {
        fetch('https://app-router.leancloud.cn/2/route?appId=' + app_id)
          .then(response => response.json())
          .then(({
            api_server
          }) => {
            fetchData('https://' + api_server);
          });
      }
    })();
  </script>



<script>
            window.imageLazyLoadSetting = {
                isSPA: false,
                preloadRatio: 1,
                processImages: null,
            };
        </script><script>window.addEventListener("load",function(){var t=/\.(gif|jpg|jpeg|tiff|png)$/i,r=/^data:image\/[a-z]+;base64,/;Array.prototype.slice.call(document.querySelectorAll("img[data-original]")).forEach(function(a){var e=a.parentNode;"A"===e.tagName&&(e.href.match(t)||e.href.match(r))&&(e.href=a.dataset.original)})});</script><script>!function(n){n.imageLazyLoadSetting.processImages=o;var e=n.imageLazyLoadSetting.isSPA,i=n.imageLazyLoadSetting.preloadRatio||1,r=Array.prototype.slice.call(document.querySelectorAll("img[data-original]"));function o(){e&&(r=Array.prototype.slice.call(document.querySelectorAll("img[data-original]")));for(var t,a=0;a<r.length;a++)0<=(t=(t=r[a]).getBoundingClientRect()).bottom&&0<=t.left&&t.top<=(n.innerHeight*i||document.documentElement.clientHeight*i)&&function(){var t,e,n,i,o=r[a];t=o,e=function(){r=r.filter(function(t){return o!==t})},n=new Image,i=t.getAttribute("data-original"),n.onload=function(){t.src=i,e&&e()},t.src!==i&&(n.src=i)}()}o(),n.addEventListener("scroll",function(){var t,e;t=o,e=n,clearTimeout(t.tId),t.tId=setTimeout(function(){t.call(e)},500)})}(this);</script></body>

</html>